#ifndef CUBES_MOVE_H
#define CUBES_MOVE_H

int min(int a, int b)
{
    return a < b ? a : b;
}

int cube_stop_atackers(int ID)
{
    int i;
    Cube_P cube;
    for(i = 0; i < CC; ++i)
    {
        cube = &cubes[i];
        if(!cube->enabled)
            continue;
        if(!cube->target)
            continue;
        if(cube->target->ID != ID) 
            continue;
        cube->target = 0;
        cube->state = State_Search;
    }
    return 1;
}

int cube_has_other_atacker(int targetID, int atackerID)
{
    int i;
    Cube_P possible_atacker;
    for(i = 0; i < CC; ++i)
    {
        possible_atacker = &cubes[i];
        if(!possible_atacker->enabled)
            continue;
        if(possible_atacker->state!=State_Moving) {
            continue;
        }
        if(possible_atacker->ID == atackerID)
            continue;
        if(possible_atacker->ID == targetID)
            continue;
        if(!possible_atacker->target)
            continue;
        if(possible_atacker->target->ID == targetID)
        {
            return 1;   
        }
    }
    return 0;
}

int who_wins(float x1, float y1, float x2, float y2, 
    float a1, float a2)
{
    float dx1, dx2, dy1, dy2, px1, py1, px2, py2;
    float l1, l2, lx1, ly1, lx2, ly2;
    dy1 = CS/2 * cos(degs_to_rads(a1));
    dx1 = CS/2 * cos(degs_to_rads(90-a1));
    dy2 = CS/2 * cos(degs_to_rads(fabs(a2)));
    dx2 = CS/2 * cos(degs_to_rads(fabs(90-a2)));
    px1 = x1 + dx1;
    py1 = y1 + dy1;
    px2 = x2 + dx2;
    py2 = y2 + dy2;
    lx1 = px1 - x2;
    ly1 = py1 - y2;
    lx2 = px2 - x1;
    ly2 = py2 - y1;
    l1 = lx1*lx1+ly1*ly1;
    l2 = lx2*lx2+ly2*ly2;
    //printf("l1 %d, l2 %d\n", (int)sqrt(l1), (int)sqrt(l2));
    //printf("a1 %d, a2 %d\n", (int)a1, (int)a2);
    return l1 < l2;
}

int cube_stop_waiters(int ID)
{
    int i;
    Cube_P waiter;
    for(i = 0; i < CC; ++i) 
    {
        waiter = &cubes[i];
        if(waiter->state != State_Waiting) 
            continue;
        if(waiter->target->ID != ID)
            continue;
        waiter->target = 0;
        waiter->state = State_Search;
    }
    return 1;
}

int cube_check_crash(Cube_P cube)
{
    int i;
    Cube_P target;
    Cube_P possible_free;
    Cube_P tmpcube;
    float x;
    float y;
    for(i = 0; i < CC; ++i) 
    {
        target = &cubes[i];
        if(!target->enabled)
            continue;
        if(target->ID == cube->ID)
            continue;
        x = fabs(cube->x - target->x);
        y = fabs(cube->y - target->y);  
        if (x*x + y*y > CS/2*CS/2+CS/2*CS/2)
            continue;  
        //if((x > 16) || (y > 16)) 
        //    continue;
        
        if(!who_wins(cube->x, cube->y, target->x, 
            target->y, cube->angle, target->angle)) {
            tmpcube = target;
            target = cube;
            cube = tmpcube;    
        }
        
        target->enabled = 0;
        ////////////
        if(target->target) {
            possible_free = target->target;
            if(!cube_has_other_atacker(possible_free->ID, 
                target->ID)) 
            {
                possible_free->state = State_Search;
                possible_free->target = 0;
                cube_stop_waiters(possible_free->ID);
            }
        }
        cube_stop_waiters(target->ID);
        target->target = 0;
        target->state = State_Disabled;
        cube_stop_atackers(target->ID);
        cube->state = State_Search;
        cube->target = 0;
        cube->level+=target->level;
        cube->level = min(cube->level, Levels_Count);
        //printf("Cube %d crashed by %d\n", 
            //target->ID, cube->ID);
    }
    return 1;
}

int cubes_move()
{
    int i;
    Cube_P cube;
    float start_speed;
    for(i = 0; i < CC; ++i) 
    {
        cube = &cubes[i];
        if(!cube->enabled)
            continue;
        if(cube->state != State_Moving)
            continue;

        cube->x += cube->dx;
        cube->y += cube->dy;
        start_speed = cube->ax*AccelK;
        if(fabs(SpeedK*start_speed) > fabs(cube->dx)) {
            cube->dx += cube->ax;
            cube->dy += cube->ay;
        }
        cube_check_crash(cube);
    }
    return 1;
}

#endif
